package com.sunwayhorizo.health.business.clinic.orders.basedef;

import java.util.ArrayList;
import java.util.List;

import javax.ejb.Stateless;

import org.jboss.seam.Component;
import org.jboss.seam.annotations.Name;

import com.sunwayhorizo.health.business.base.BaseManager;
import com.sunwayhorizo.health.business.clinic.orders.query.OrdersQueryLocal;
import com.sunwayhorizo.health.business.dto.PageDTO;
import com.sunwayhorizo.health.business.dto.ResultsDTO;
import com.sunwayhorizo.health.business.dto.clinic.orders.ObsOrProDTO;
import com.sunwayhorizo.health.business.dto.econ.InvoiceElementDTO;
import com.sunwayhorizo.health.common.DataTypeUtil;
import com.sunwayhorizo.health.common.ListUtil;
import com.sunwayhorizo.health.common.StrUtil;
import com.sunwayhorizo.health.hl7.common.Hl7Exception;
import com.sunwayhorizo.health.hl7.datatypes.CE;
import com.sunwayhorizo.health.hl7.datatypes.CS;
import com.sunwayhorizo.health.hl7.datatypes.II;
import com.sunwayhorizo.health.hl7.rim.Act;
import com.sunwayhorizo.health.hl7.rim.ActParticipation;
import com.sunwayhorizo.health.hl7.rim.ActRelationship;
import com.sunwayhorizo.health.hl7.rim.ControlAct;
import com.sunwayhorizo.health.hl7.rim.InvoiceElement;
import com.sunwayhorizo.health.hl7.rim.Observation;
import com.sunwayhorizo.health.hl7.rim.Procedure;
import com.sunwayhorizo.health.hl7.rim.Role;
import com.sunwayhorizo.health.hl7.vocabulary.ActClass;
import com.sunwayhorizo.health.hl7.vocabulary.ActCode;
import com.sunwayhorizo.health.hl7.vocabulary.ActIICode;
import com.sunwayhorizo.health.hl7.vocabulary.ActMood;
import com.sunwayhorizo.health.hl7.vocabulary.ActRelationshipType;
import com.sunwayhorizo.health.hl7.vocabulary.Direction;
import com.sunwayhorizo.health.hl7.vocabulary.ParticipationType;

/**
 * @ClassName ProcedureDefManager <br>
 * @PackageName com.sunwayhorizo.health.business.clinic.orders.basedef <br>
 * @Description 诊断观察(检查 检验)定义session bean <br>
 * @Author jinzw <br>
 * @Date 2010-08-23 <br>
 * @Version 1.0 <br>
 * @ModifiedDesc <br>
 * @ModifiedDate <br>
 * @ModifiedBy <br>
 * @Copyright 2010-2020 北京三维海容 All Rights Reserved. <br>
 */

@Name("ProcedureDefManager")
@Stateless
public class ProcedureDefManager extends BaseManager implements ProcedureDefManagerLocal
{
    private InvoiceElementDefManagerLocal inveElementDefManager = (InvoiceElementDefManagerLocal) Component.getInstance("InvoiceElementDefManager");
    private OrdersQueryLocal ordersQuery = (OrdersQueryLocal) Component.getInstance("OrdersQuery");
    
    @Override
    public ResultsDTO newProcedureDef(ObsOrProDTO obsOrProDTO) throws Hl7Exception
    {
        if(obsOrProDTO == null)
        {
            log.info("治疗 护理信息为空，不能添加");
            return this.getResultsDTO("治疗 护理信息为空，不能添加", false, null);
        }
        
        //创建检查检验动作
        CE ce = DataTypeUtil.getCE(obsOrProDTO.getCode());
        Procedure proc = this.getActFactory().newProcedure(ActMood.DEF, ce, null);
        
        //给检查检验动作赋值
        proc = converprocFormProcDto(proc,obsOrProDTO);
        
        //执行科室角色参与到检查检验动作中
        if(StrUtil.isNotEmpty(obsOrProDTO.getExecutDeptRimRoleId()))
        {
            Role exvetuDeptRole = baseQuery.findRoleById(Long.valueOf(obsOrProDTO.getExecutDeptRimRoleId()));
            ActParticipation part = getActFactory().newActParticipation();
            part.setTypeCode(ParticipationType.SBJ);
            addParticipation(exvetuDeptRole, part);
        }
        
        //检查 检验费用信息动作关联到检查 检验定义动作中
        if(ListUtil.isNotEmpty(obsOrProDTO.getInvoiceElementList()))
        {
            for(InvoiceElementDTO invoiceElement : obsOrProDTO.getInvoiceElementList())
            {
                InvoiceElement inve = inveElementDefManager.newInvoiceElementDet(invoiceElement);
                if(inve != null)
                {
                    ActRelationship relation = getActFactory().newActRelationship();
                    relation.setTypeCode(ActRelationshipType.CHRG);
                    addRelationship(inve, relation, Direction.SOURCE);
                }
            }
        }
        
        // 创建ControlAct
        ControlAct control = newControlAct(proc); 
        
        //持久化ControlAct
        save(control);
        log.info("创建治疗 护理信息成功 actid="+proc.getActId());
        return this.getResultsDTO("创建治疗 护理信息信息成功", true, proc.getActId());
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Override
    public ResultsDTO delProcedureDef(List ids) throws Hl7Exception
    {
        if (ListUtil.isEmpty(ids))
        {
            log.info("删除治疗信息失败，数据为空");
            return getResultsDTO("删除治疗信息失败，数据为空", false, null);
        }
        for(int i=0; i<ids.size(); i++)
        {
            String id = (String)ids.get(i);
            Act act = baseQuery.findActByActId(Long.valueOf(id));
            CS actCode = null;
            if(act.getCode().code().toString().equals(ActCode.TREAT.code().toString()))
            {
                actCode = ActCode.TREAT;
            }
            if(act.getCode().code().toString().equals(ActCode.SURGERY.code().toString()))
            {
                actCode = ActCode.SURGERY; 
            }
            if(act.getCode().code().toString().equals(ActCode.ANAEROBIC.code().toString()))
            {
                actCode = ActCode.ANAEROBIC; 
            }
            if(act.getCode().code().toString().equals(ActCode.NURSING.code().toString()))
            {
                actCode = ActCode.NURSING; 
            }
            if(act.getCode().code().toString().equals(ActCode.OTHER.code().toString()))
            {
                actCode = ActCode.OTHER; 
            }
            List<InvoiceElement> inveList = (List<InvoiceElement>)act.getTargetActListBySourceAct(ActClass.INVE, actCode);
            int j= delete(act,null);
            if(j == 0)
            {
                log.info("治疗基本信息删除失败");
            }
            int k = batchDelete(inveList,null);
            if(k == 0)
            {
                log.info("治疗费用信息删除失败");
            }
        }
        return getResultsDTO("删除治疗基本信息成功", true, null);
    }

    @SuppressWarnings({ "unchecked", "null" })
    @Override
    public ResultsDTO updProcedureDef(ObsOrProDTO obsOrProDTO) throws Hl7Exception
    {
        if(obsOrProDTO == null && StrUtil.isEmpty(obsOrProDTO.getActId()))
        {
            log.info("治疗信息为空,不能进行修改");
            return this.getResultsDTO("治疗信息为空，不能修改", false, null);
        }
        
        //得到治疗动作
        Procedure proc = (Procedure)baseQuery.findActByActId(Long.valueOf(obsOrProDTO.getActId()));
        
        //修改治疗动作信息
        proc = converprocFormProcDto(proc,obsOrProDTO);
        
       //修改治疗费用信息
        CS actCode = null;
        if(proc.getCode().code().toString().equals(ActCode.TREAT.code().toString()))
        {
            actCode = ActCode.TREAT;
        }
        if(proc.getCode().code().toString().equals(ActCode.SURGERY.code().toString()))
        {
            actCode = ActCode.SURGERY; 
        }
        if(proc.getCode().code().toString().equals(ActCode.ANAEROBIC.code().toString()))
        {
            actCode = ActCode.ANAEROBIC; 
        }
        if(proc.getCode().code().toString().equals(ActCode.NURSING.code().toString()))
        {
            actCode = ActCode.NURSING; 
        }
        if(proc.getCode().code().toString().equals(ActCode.OTHER.code().toString()))
        {
            actCode = ActCode.OTHER; 
        }
       List<InvoiceElement> inveList = (List<InvoiceElement>)proc.getTargetActListBySourceAct(ActClass.INVE, actCode);
       batchDelete(inveList,null);
       //治疗费用信息动作关联到治疗定义动作中
       if(ListUtil.isNotEmpty(obsOrProDTO.getInvoiceElementList()))
       {
           for(InvoiceElementDTO invoiceElement : obsOrProDTO.getInvoiceElementList())
           {
               InvoiceElement inve = inveElementDefManager.newInvoiceElementDet(invoiceElement);
               if(inve != null)
               {
                   proc.addOBActRelationship(ActRelationshipType.CHRG, inve);
               }
           }
       }
       
       update(proc);
       log.info("修改治疗动作信息成功"+proc.getActId());
       
       return this.getResultsDTO("治疗基本信息修改成功", true, proc.getActId().toString());
    }

    @SuppressWarnings("unchecked")
    @Override
    public ResultsDTO findProcedureDefList(String code,String ywm,PageDTO pageDto) throws Hl7Exception
    {
        if(StrUtil.isEmpty(code) ) return this.getResultsDTO("项目编码为空，不能查询", false, null);
        List<Procedure> procList = (List<Procedure>)ordersQuery.findCountObsOrProcByCond(code, ywm, pageDto.getPageNo(), pageDto.getPageSize());
        List<ObsOrProDTO> obsDtoList = new ArrayList<ObsOrProDTO>();
        if(ListUtil.isNotEmpty(procList))
        {
            for(Procedure proc : procList)
            {
                ObsOrProDTO obsOrProDTO =  converProcDtoFormProc(proc);
                obsDtoList.add(obsOrProDTO);
            }
            pageDto.setTotalRecord((int)ordersQuery.findObsOrProcByCond(code));
        }
        return this.getResultsDTO("治疗项目查询成功", true, obsDtoList, pageDto);
    }
    
    private ObsOrProDTO converProcDtoFormProc(Procedure proc) throws Hl7Exception
    {
        ObsOrProDTO obsOrProDTO = new ObsOrProDTO();
        obsOrProDTO.setActId(proc.getActId()+"");
        II treatId = proc.getId(ActIICode.TREATITEMCODE);
        II surgerytId = proc.getId(ActIICode.SURGERYITEMCODE);
        II anaerobicId = proc.getId(ActIICode.ANAEROBICITEMCODE);
        II nursingId = proc.getId(ActIICode.NURSINGITEMCODE);
        II otherId = proc.getId(ActIICode.OTHERITEMCODE);
        if(treatId != null && treatId.isNull().isFalse())
        {
            obsOrProDTO.setId(treatId.extension().toString());
        }
        if(surgerytId != null && surgerytId.isNull().isFalse())
        {
            obsOrProDTO.setId(surgerytId.extension().toString());
        }
        if(anaerobicId != null && anaerobicId.isNull().isFalse())
        {
            obsOrProDTO.setId(anaerobicId.extension().toString());
        }
        if(nursingId != null && nursingId.isNull().isFalse())
        {
            obsOrProDTO.setId(nursingId.extension().toString());
        }
        if(otherId != null && otherId.isNull().isFalse())
        {
            obsOrProDTO.setId(otherId.extension().toString());
        }
        obsOrProDTO.setTitle(proc.getTitle().toString());
        obsOrProDTO.setInterpretation(this.getDictionaryFactory().getDictionaryDTOByCe(proc.getMethodCode()));
        obsOrProDTO.setInvoiceElementList(converInveElementDTOListFormInves(proc));
        return obsOrProDTO;
    }
    
    private Procedure converprocFormProcDto(Procedure proc,ObsOrProDTO procDTO) throws Hl7Exception
    {

        if(proc == null) return null;
        
        //治疗项目代码
        if(StrUtil.isNotEmpty(procDTO.getId()))
        {
            String identifileName = "";
            if(procDTO.getCode().equals(ActCode.TREAT.code().toString()))
            {
                identifileName = ActIICode.TREATITEMCODE.toString();
            }
            if(procDTO.getCode().equals(ActCode.SURGERY.code().toString()))
            {
                identifileName = ActIICode.SURGERYITEMCODE.toString(); 
            }
            if(procDTO.getCode().equals(ActCode.ANAEROBIC.code().toString()))
            {
                identifileName = ActIICode.ANAEROBICITEMCODE.toString(); 
            }
            if(procDTO.getCode().equals(ActCode.NURSING.code().toString()))
            {
                identifileName = ActIICode.NURSINGITEMCODE.toString(); 
            }
            if(procDTO.getCode().equals(ActCode.OTHER.code().toString()))
            {
                identifileName = ActIICode.OTHERITEMCODE.toString(); 
            }
            II id = DataTypeUtil.getII(root, procDTO.getId(), identifileName);
            proc.setId(id);
        }
        
        //治疗项目名称
        if(StrUtil.isNotEmpty(procDTO.getTitle()))
        {
            proc.setTitle(DataTypeUtil.getST(procDTO.getTitle())); 
        }
        //手术等级
        if(procDTO.getInterpretation() != null && StrUtil.isNotEmpty(procDTO.getInterpretation().getConceptCode()))
        {
            proc.setMethodCode(getDictionaryFactory().getCeByDictionaryDTO(procDTO.getInterpretation()));
        }
        
        return proc;
    }
    
  //组装药品费用信息dto集合
    @SuppressWarnings({ "unchecked" })
    private List<InvoiceElementDTO> converInveElementDTOListFormInves(Procedure proc) throws Hl7Exception
    {
        List<InvoiceElementDTO> inveDtolist = new ArrayList<InvoiceElementDTO>();
        List<InvoiceElement> inves = (List<InvoiceElement>)proc.getTargetActListBySourceAct(ActClass.INVE,proc.getCode());
        if(ListUtil.isNotEmpty(inves))
        {
            for(InvoiceElement inve : inves)
            {
                InvoiceElementDTO inveDto = inveElementDefManager.converInvoiceElementDTOFormInve(inve);
                inveDtolist.add(inveDto);
            }
        }
        return inveDtolist;
    }

}
